package cn.chiship.framework.upms.core.aspect;

import cn.chiship.framework.common.annotation.DataScope;
import cn.chiship.framework.common.enums.DataScopeEnum;
import cn.chiship.framework.common.pojo.dto.BaseQueryEntityDto;
import cn.chiship.framework.upms.biz.user.service.UpmsUserOrganizationService;
import cn.chiship.sdk.cache.service.UserCacheService;
import cn.chiship.sdk.cache.vo.CacheOrganizationVo;
import cn.chiship.sdk.cache.vo.CacheRoleVo;
import cn.chiship.sdk.cache.vo.CacheUserVO;
import cn.chiship.sdk.core.util.StringUtil;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据过滤处理
 *
 * @author lj
 */
@Aspect
@Component
public class DataScopeAspect {

	/**
	 * 数据权限过滤关键字
	 */
	public static final String DATA_SCOPE = "dataScope";

	@Resource
	private UserCacheService userCacheService;

	@Resource
	private UpmsUserOrganizationService upmsUserOrganizationService;

	@Before("@annotation(controllerDataScope)")
	public void doBefore(JoinPoint point, DataScope controllerDataScope) {
		clearDataScope(point);
		handleDataScope(point, controllerDataScope);
	}

	protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) {

		// 获取当前的用户
		CacheUserVO userVO = userCacheService.getUser();
		if (!StringUtil.isNull(userVO)) {
			dataScopeFilter(joinPoint, userVO);
		}
	}

	/**
	 * 数据范围过滤
	 * @param joinPoint 切点
	 * @param cacheUserVO 用户
	 */
	public void dataScopeFilter(JoinPoint joinPoint, CacheUserVO cacheUserVO) {

		List<String> userIds = new ArrayList<>();
		List<String> orgIds = new ArrayList<>();

		Object params = joinPoint.getArgs()[joinPoint.getArgs().length - 1];
		if (!StringUtil.isNull(params) && params instanceof BaseQueryEntityDto) {
			BaseQueryEntityDto baseEntity = (BaseQueryEntityDto) params;
			baseEntity.setDataScopeAll(false);

			for (CacheRoleVo role : cacheUserVO.getCacheRoleVos()) {
				Byte dataScope = role.getDataScope();
				if (DataScopeEnum.DATA_SCOPE_ALL.getType().equals(dataScope)) {
					baseEntity.setDataScopeAll(true);
					break;
				}
				else if (DataScopeEnum.DATA_SCOPE_CUSTOM.getType().equals(dataScope)) {

				}
				else if (DataScopeEnum.DATA_SCOPE_ORG.getType().equals(dataScope)) {
					CacheOrganizationVo organizationVo = cacheUserVO.getCacheOrganizationVo();
					if (!StringUtil.isNull(organizationVo)) {
						orgIds.add(organizationVo.getId());
					}
					else {
						orgIds.add("-1");
					}
				}
				else if (DataScopeEnum.DATA_SCOPE_ORG_AND_CHILD.getType().equals(dataScope)) {
					CacheOrganizationVo organizationVo = cacheUserVO.getCacheOrganizationVo();
					List<String> temp = upmsUserOrganizationService
							.listOrgIdByTreeNumber(organizationVo.getTreeNumber());
					if (!temp.isEmpty()) {
						orgIds.addAll(temp);
					}
					else {
						orgIds.add("-1");
					}
				}
				else if (DataScopeEnum.DATA_SCOPE_SELF.getType().equals(dataScope)) {
					userIds.add(StringUtil.getString(cacheUserVO.getId()));
				}
			}

			baseEntity.setUserIds(userIds);
			baseEntity.setOrgIds(orgIds);
			baseEntity.getParams().put("orgIds", orgIds);
			baseEntity.getParams().put("userIds", userIds);

		}

	}

	/**
	 * 拼接权限sql前先清空params.dataScope参数防止注入
	 */
	private void clearDataScope(final JoinPoint joinPoint) {
		Object params = joinPoint.getArgs()[joinPoint.getArgs().length - 1];
		if (!StringUtil.isNull(params) && params instanceof BaseQueryEntityDto) {
			BaseQueryEntityDto baseEntity = (BaseQueryEntityDto) params;
			baseEntity.getParams().put(DATA_SCOPE, "");
		}
	}

}
